﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace Warframe_Character_Builder
{
    public partial class WarframeCharacterBuilder : Form
    {
        ModForm modWindow;
        List<Warframe> warframes;
        List<Weapon> weapons;
        List<Mod> mods;
        int iCurrentWarframe;
        int iCurrentWeapon;
        int iCurrentModSlot;

        public WarframeCharacterBuilder()
        {
            InitializeComponent();

            warframes = new List<Warframe>();
            weapons = new List<Weapon>();
            mods = new List<Mod>();
            modWindow = null;
            iCurrentWarframe =
                iCurrentWeapon = 
                iCurrentModSlot = 0;
            
            // 13 warframes
            // 53 weapons
            // 135 total mods(87 mods, 48 ability mods)
            //Import Everything
            ImportWarframes();
            ImportAllWeapons();

            WarframeCB.SelectedIndex = 0;
            WeaponCB.SelectedIndex = 0;
        }

        public void ImportWarframes()
        {
            XElement WarframeRoot = XElement.Load("Warframes.xml");
            warframes.Clear();

            IEnumerable<XElement> EWarframes = WarframeRoot.Elements("Warframe");
            foreach (XElement xWarframe in EWarframes)
            {
                // import warframe values
                XAttribute xName = xWarframe.Attribute("Name");
                XElement xHealth = xWarframe.Element("Health");
                XElement xShield = xWarframe.Element("Shield");
                XElement xEnergy = xWarframe.Element("Energy");
                XElement xArmor = xWarframe.Element("Armor");
                XElement xRecharge = xWarframe.Element("Recharge");
                XElement xSpeed = xWarframe.Element("Speed");

                // import polarities
                List<Polarity> newPolarities = new List<Polarity>();
                XElement xPolarities = xWarframe.Element("Polarities");
                IEnumerable<XElement> EPolarities = xPolarities.Elements("Polarity");
                foreach (XElement xPolarity in EPolarities)
                {
                    XAttribute xPName = xPolarity.Attribute("Type");
                    XElement xAmount = xPolarity.Element("Amount");

                    for (int i = 0; i < Convert.ToInt32(xAmount.Value); ++i)
                    {
                        Polarity newPolarity = new Polarity(Convert.ToInt32(xPName.Value));
                        newPolarities.Add(newPolarity);
                    }
                }

                Warframe newWarframe = new Warframe(xName.Value, 0, false, 0, newPolarities, 
                    (float)Convert.ToDouble(xHealth.Value),
                    (float)Convert.ToDouble(xShield.Value),
                    (float)Convert.ToDouble(xEnergy.Value),
                    (float)Convert.ToDouble(xArmor.Value),
                    (float)Convert.ToDouble(xRecharge.Value),
                    (float)Convert.ToDouble(xSpeed.Value));

                warframes.Add(newWarframe);
            }
        }

        public void ImportGuns(IEnumerable<XElement> IEelements, int Type)
        {
            foreach (XElement xElement in IEelements)
            {
                XAttribute xName = xElement.Attribute("Name");
                XElement xDmg = xElement.Element("Damage");
                XElement xFR = xElement.Element("RateFire");
                XElement xAcc = xElement.Element("Accuracy");
                XElement xMag = xElement.Element("Magazine");
                XElement xAmmo = xElement.Element("AmmoCapacity");
                XElement xReload = xElement.Element("Reload");
                XElement xCrit = xElement.Element("CriticalChance");
                XElement xCritDmg = xElement.Element("CriticalDamage");
                XElement xNumPol = xElement.Element("NumPolarity");

                List<Polarity> newPolarities = new List<Polarity>();
                if (Convert.ToInt32(xNumPol.Value) >= 1)
                {
                    for (int i = 0; i < Convert.ToInt32(xNumPol.Value); ++i)
                    {
                        XElement xType = xElement.Element("PolarityType");
                        Polarity newPolarity = new Polarity(Convert.ToInt32(xType.Value));
                        newPolarities.Add(newPolarity);
                    }
                }

                Weapon newWeapon = new Weapon(Convert.ToString(xName.Value), 0, 0, false, 0, newPolarities,
                    (float)Convert.ToDouble(xDmg.Value),
                    (float)Convert.ToDouble(xAcc.Value),
                    (float)Convert.ToDouble(xReload.Value), 0, 0,
                    (float)Convert.ToDouble(xCrit.Value),
                    (float)Convert.ToDouble(xCritDmg.Value),
                    (float)Convert.ToDouble(xFR.Value),
                    Convert.ToInt32(xMag.Value),
                    Convert.ToInt32(xAmmo.Value));

                weapons.Add(newWeapon);
            }
        }

        public void ImportMelees(IEnumerable<XElement> IEelements)
        {
            foreach (XElement xElement in IEelements)
            {
                XAttribute xName = xElement.Attribute("Name");
                XElement xDmg = xElement.Element("Damage");
                XElement xFR = xElement.Element("RateFire");
                XElement xCHSpeed = xElement.Element("ChargeSpeed");
                XElement xCHDmg = xElement.Element("ChargeDamage");
                XElement xCrit = xElement.Element("CriticalChance");
                XElement xCritDmg = xElement.Element("CriticalDamage");
                XElement xNumPol = xElement.Element("NumPolarity");

                List<Polarity> newPolarities = new List<Polarity>();
                if (Convert.ToInt32(xNumPol.Value) >= 1)
                {
                    for (int i = 0; i < Convert.ToInt32(xNumPol.Value); ++i)
                    {
                        XElement xType = xElement.Element("PolarityType");
                        Polarity newPolarity = new Polarity(Convert.ToInt32(xType.Value));
                        newPolarities.Add(newPolarity);
                    }
                }

                Weapon newWeapon = new Weapon(Convert.ToString(xName.Value), 3, 0, false, 0, newPolarities,
                    (float)Convert.ToDouble(xDmg.Value), 0.0f ,0.0f,
                    (float)Convert.ToDouble(xCHSpeed.Value),
                    (float)Convert.ToDouble(xCHDmg.Value),
                    (float)Convert.ToDouble(xCrit.Value),
                    (float)Convert.ToDouble(xCritDmg.Value),
                    (float)Convert.ToDouble(xFR.Value), 0, 0);

                weapons.Add(newWeapon);
            }
        }

        public void ImportAllWeapons()
        {
            XElement WeaponRoot = XElement.Load("PrimaryWeapons.xml");
            weapons.Clear();

            //Load in Rifles
            XElement xRifles = WeaponRoot.Element("Rifles");
            IEnumerable<XElement> ERifles = xRifles.Elements("Rifle");
            ImportGuns(ERifles,0);
            
            // Load in Shotguns
            XElement xShotguns = WeaponRoot.Element("Shotguns");
            IEnumerable<XElement> EShotguns = xShotguns.Elements("Shotgun");
            ImportGuns(EShotguns,1);

            // Load in Pistols
            WeaponRoot = XElement.Load("SecondaryWeapons.xml");
            XElement xPistols = WeaponRoot.Element("Pistols");
            IEnumerable<XElement> EPistols = xPistols.Elements("Pistol");
            ImportGuns(EPistols,2);

            // Load in Short Melee
            WeaponRoot = XElement.Load("MeleeWeapons.xml");
            XElement xShortMelees = WeaponRoot.Element("ShortMelees");
            IEnumerable<XElement> EShortMelees = xShortMelees.Elements("ShortMelee");
            ImportMelees(EShortMelees);

            // Load in Long Melee
            XElement xLongMelees = WeaponRoot.Element("LongMelees");
            IEnumerable<XElement> ELongMelees = xLongMelees.Elements("LongMelee");
            ImportMelees(ELongMelees);
            
            // Load in Heavy Melee
            XElement xHeavyMelees = WeaponRoot.Element("HeavyMelees");
            IEnumerable<XElement> EHeavyMelees = xHeavyMelees.Elements("HeavyMelee");
            ImportMelees(EHeavyMelees);

        }

        void SetWarframeStats(Warframe warframe)
        {
            WarframeLevelNUD.Value = warframe.Level;
            WarframeSCCB.SelectedIndex = Convert.ToInt32(warframe.IsSuperCharged);
            WarframeMPTB.Text = Convert.ToString(warframe.ModPoints);
            BaseHealthTB.Text = Convert.ToString(warframe.Health);
            BaseEnergyTB.Text = Convert.ToString(warframe.Energy);
            BaseArmorTB.Text = Convert.ToString(warframe.Armor);
            BaseShieldTB.Text = Convert.ToString(warframe.Shield);
            BaseRechargeTB.Text = Convert.ToString(warframe.Recharge);
            BaseSpeedTB.Text = Convert.ToString(warframe.Speed);
        }

        void SetWeaponStats(Weapon weapon)
        {
            WeaponLevelNUD.Value = weapon.Level;
            WeaponSCCB.SelectedIndex = Convert.ToInt32(weapon.IsSuperCharged);
            WeaponMPTB.Text = Convert.ToString(weapon.ModPoints);
            BaseDmgTB.Text = Convert.ToString(weapon.Damage);
            BaseAccTB.Text = Convert.ToString(weapon.Accuracy);
            BaseReloadTB.Text = Convert.ToString(weapon.Reload);
            BaseFireRateTB.Text = Convert.ToString(weapon.FireRate);
            BaseMagTB.Text = Convert.ToString(weapon.Magazine);
            BaseAmmoCapTB.Text = Convert.ToString(weapon.AmmoCapacity);
            BaseCritTB.Text = Convert.ToString(weapon.CriticalChance);
            BaseCritDmgTB.Text = Convert.ToString(weapon.CriticalDamage);
            BaseChgDmgTB.Text = Convert.ToString(weapon.ChargeDamage);
        }

        void ModForm_AddMod(object sender, EventArgs e)
        {
            ModForm tempModForm = sender as ModForm;
            if (tempModForm != null)
            {
                // warframe tab
                if (WarframeWeaponTab.SelectedIndex == 0)
                {
                    // warframe mod
                    if (tempModForm.ModTC.SelectedIndex == 0)
                    {
                        // TODO UPDATE WARFRAME STAT WITH MOD
                        warframes[iCurrentWarframe].Mods[iCurrentModSlot] = tempModForm.Mods[tempModForm.ModTC.SelectedIndex][tempModForm.iCurrentwarframeMod];
                    }
                    // Error Window
                    else
                    {
                        MessageBox.Show("That is not a Warframe Mod!","Mod Error");
                    }
                }
                // weapon tab
                else
                {

                }
            }
        }

        private void ModButton1_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 0;
            }
        }

        private void ModButton2_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 1;
            }
        }

        private void ModButton3_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 2;
            }
        }

        private void ModButton4_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 3;
            }
        }

        private void ModButton5_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 4;
            }
        }

        private void ModButton6_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 5;
            }
        }

        private void ModButton7_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 6;
            }
        }

        private void ModButton8_Click(object sender, EventArgs e)
        {
            // Open Mod Window
            if (modWindow == null)
            {
                modWindow = new ModForm();
                modWindow.FormClosed += modWindow_FormClosed;
                modWindow.AddMod += new EventHandler(ModForm_AddMod);
                modWindow.ShowDialog();
                iCurrentModSlot = 7;
            }
        }

        void modWindow_FormClosed(object sender, FormClosedEventArgs e)
        {
            // close Mod Window
            modWindow = null;
        }

        private void WarframeCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            // set current warframe and set all stats
            iCurrentWarframe = WarframeCB.SelectedIndex;
            SetWarframeStats(warframes[iCurrentWarframe]);
        }

        private void WarframeLevelNUD_ValueChanged(object sender, EventArgs e)
        {
            // update warframe level
            warframes[iCurrentWarframe].Level = Convert.ToInt32(WarframeLevelNUD.Value);
            // update mod points
            if (warframes[iCurrentWarframe].IsSuperCharged == true)
                warframes[iCurrentWarframe].ModPoints = Convert.ToInt32(WarframeLevelNUD.Value) * 2;
            else
                warframes[iCurrentWarframe].ModPoints = Convert.ToInt32(WarframeLevelNUD.Value);
            WarframeMPTB.Text = Convert.ToString(warframes[iCurrentWarframe].ModPoints);
        }

        private void WarframeSCCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            // update mod points
            if (warframes[iCurrentWarframe].IsSuperCharged != Convert.ToBoolean(WarframeSCCB.SelectedIndex))
            {
                warframes[iCurrentWarframe].IsSuperCharged = Convert.ToBoolean(WarframeSCCB.SelectedIndex);
                if (warframes[iCurrentWarframe].IsSuperCharged)
                {
                    warframes[iCurrentWarframe].ModPoints += warframes[iCurrentWarframe].Level;
                    WarframeMPTB.Text = Convert.ToString(warframes[iCurrentWarframe].ModPoints);
                }
                else
                {
                    warframes[iCurrentWarframe].ModPoints -= warframes[iCurrentWarframe].Level;
                    WarframeMPTB.Text = Convert.ToString(warframes[iCurrentWarframe].ModPoints);
                }
            }
        }

        private void WeaponCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            // set current weapon and set all stats
            for(int i = 0; i < weapons.Count; ++i)
            {
                if(WeaponCB.SelectedItem.ToString() == weapons[i].Name)
                {
                    iCurrentWeapon = i;
                    break;
                }
            }
            SetWeaponStats(weapons[iCurrentWeapon]);
        }

        private void WeaponLevelNUD_ValueChanged(object sender, EventArgs e)
        {
            // update weapon level
            weapons[iCurrentWeapon].Level = Convert.ToInt32(WeaponLevelNUD.Value);
            if (weapons[iCurrentWeapon].IsSuperCharged == true)
                weapons[iCurrentWeapon].ModPoints = Convert.ToInt32(WeaponLevelNUD.Value) * 2;
            else
                weapons[iCurrentWeapon].ModPoints = Convert.ToInt32(WeaponLevelNUD.Value);
            WeaponMPTB.Text = Convert.ToString(weapons[iCurrentWeapon].ModPoints);
        }

        private void WeaponSCCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            // update weapon mod points
            if (weapons[iCurrentWeapon].IsSuperCharged != Convert.ToBoolean(WeaponSCCB.SelectedIndex))
            {
                weapons[iCurrentWeapon].IsSuperCharged = Convert.ToBoolean(WeaponSCCB.SelectedIndex);
                if (weapons[iCurrentWeapon].IsSuperCharged)
                {
                    weapons[iCurrentWeapon].ModPoints += weapons[iCurrentWeapon].Level;
                    WeaponMPTB.Text = Convert.ToString(weapons[iCurrentWeapon].ModPoints);
                }
                else
                {
                    weapons[iCurrentWeapon].ModPoints -= weapons[iCurrentWeapon].Level;
                    WeaponMPTB.Text = Convert.ToString(weapons[iCurrentWeapon].ModPoints);
                }
            }
        }

        private void WeaponMPTB_TextChanged(object sender, EventArgs e)
        {
            // update current weapon mod points
            weapons[iCurrentWeapon].CurrentModPoints = weapons[iCurrentWeapon].ModPoints;
            ModPointsLeftValueLabel.Text = Convert.ToString(weapons[iCurrentWeapon].CurrentModPoints);
        }

        private void WarframeMPTB_TextChanged(object sender, EventArgs e)
        {
            // update current warframe mod points
            warframes[iCurrentWarframe].CurrentModPoints = warframes[iCurrentWarframe].ModPoints;
            ModPointsLeftValueLabel.Text = Convert.ToString(warframes[iCurrentWarframe].CurrentModPoints);
        }

        private void WarframeWeaponTab_SelectedIndexChanged(object sender, EventArgs e)
        {
            // update current mod points
            // Warframe Tab
            if (WarframeWeaponTab.SelectedIndex == 0)
            {
                warframes[iCurrentWarframe].CurrentModPoints = warframes[iCurrentWarframe].ModPoints;
                ModPointsLeftValueLabel.Text = Convert.ToString(warframes[iCurrentWarframe].CurrentModPoints);
            }
            // Weapon Tab
            else
            {
                weapons[iCurrentWeapon].CurrentModPoints = weapons[iCurrentWeapon].ModPoints;
                ModPointsLeftValueLabel.Text = Convert.ToString(weapons[iCurrentWeapon].CurrentModPoints);
            }
        }
    }
}
